
namespace Demo2
{ 
    using System;
    using System.Diagnostics;
    using System.Collections;
    public class Myclass
    {
        [Conditional("DEBUG")]
        public static void Message(string msg)
        {
            Console.WriteLine(msg);
        }
    }
    /*
        Obsolete可以标注方法为过时
     */
    class Test
    {
        [Obsolete("该方法已过时")]
        static public void function1()
        {
            Myclass.Message("In Function 1.");
            function2();
        }
        static public void function2()
        {
            Myclass.Message("In Function 2.");
        }
    }
    /*
        访问器，将getter和setter方法当成属性访问，类似python property
     */
    class AccessorsTest
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

    /*
        索引器，实现public string this[int i]实现k[i]的数组型取值
            实现public IEnumerator GetEnumerator()方法，可以让该类可以在foreach中使用
            
     */
    class IndexerTest
    {
        private string[] names = new string[size];
        private const int size = 5;
        public string this[int i]
        {
            get
            {
                return names[i];
            }
            set
            {
                names[i] = value;
            }
        }
        
        public IEnumerator GetEnumerator()
        {
            return new Enumerator(this);
        }

        private class Enumerator : IEnumerator
        {

            private int idx = -1;
            private IndexerTest indexer;
            public Enumerator(IndexerTest indexer)
            {
                this.indexer = indexer;
            }
            public bool MoveNext()
            {
                if (++idx < size)
                    return true;
                else
                    return false;
            }

            public void Reset()
            {
                idx = -1;
            }
            public object Current 
            { 
                get
                {
                    return indexer.names[idx];
                }
            }
        }
    }

    /*
        委托 Delegate，类似函数指针
     */
    class DelegateTest
    {
        public delegate void Callable(ref int x);
        public static int Sum(int a, int b, Callable call)
        {
            int t = a + b;
            if (call != null)
            {
                call(ref t);
            }
            return t;
        }
    }

    /*
        事件 Event
     */
    class EventTest
    {
        private int num;
        public delegate void NumHandler();
        public event NumHandler handler;
        
        public void OnNumChanged()
        {
            if (handler != null)
            {
                handler();
                Console.WriteLine("changed");
            }
            else
            {
                Console.WriteLine("no changed");
            }
        }
        public void setNum(int value)
        {
            num = value;
            OnNumChanged();
        }
    }

    /*
        反射
     */
    [AttributeUsage(AttributeTargets.Class |
            AttributeTargets.Constructor |
            AttributeTargets.Field |
            AttributeTargets.Method |
            AttributeTargets.Property,
        AllowMultiple = true)]
    public class DebugInfo : System.Attribute
    {
        private int bugNo;
        private string developer;
        private string lastReview;
        public string message;

        public DebugInfo(int bg, string dev, string d)
        {
            this.bugNo = bg;
            this.developer = dev;
            this.lastReview = d;
        }

        public int BugNo
        {
            get
            {
                return bugNo;
            }
        }
        public string Developer
        {
            get
            {
                return developer;
            }
        }
        public string LastReview
        {
            get
            {
                return lastReview;
            }
        }
        public string Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }
    }
    [DebugInfo(1, "frans", "2018-08-23")]
    public class Rectangle
    {
        private float length;
        private float width;
        public Rectangle(float l, float w)
        {
            this.length = l;
            this.width = w;
        }
        public float GetArea()
        {
            return length * width;
        }
    }
    
}
